package com.zjun.demo.experimentaldemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

public class RemoteViewContainer extends ViewGroup {
    private static final String TAG = "RemoteViewContainer";
    private static final int INVALID_POINTER_ID = -1;
    private static final float MIN_SCALE = 1.0f;
    private static final float MAX_SCALE = 3.0f;

    private View remoteView;
    private float scaleFactor = 1.0f;
    private float translationX = 0f;
    private float translationY = 0f;

    // 触摸相关变量
    private float lastTouchX, lastTouchY;
    private int activePointerId = INVALID_POINTER_ID;
    private float lastTouchDistance;
    private boolean isScaling = false;
    private boolean isDragging = false;
    private long touchDownTime;

    public RemoteViewContainer(Context context) {
        super(context);
        init();
    }

    public RemoteViewContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RemoteViewContainer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setChildrenDrawingOrderEnabled(true);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (getChildCount() > 0) {
            remoteView = getChildAt(0);
            // 初始时强制子View填充容器
            remoteView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (remoteView != null) {
            // 强制子View测量为容器大小
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            remoteView.measure(
                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
            );
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (remoteView == null) return;

        int width = right - left;
        int height = bottom - top;

        // 初始布局时子View填满容器
        if (scaleFactor == 1.0f && translationX == 0 && translationY == 0) {
            remoteView.layout(0, 0, width, height);
        } else {
            // 计算缩放后的实际尺寸
            int scaledWidth = (int) (width * scaleFactor);
            int scaledHeight = (int) (height * scaleFactor);

            // 计算子View的布局位置（居中 + 平移）
            int childLeft = (width - scaledWidth) / 2 + (int) translationX;
            int childTop = (height - scaledHeight) / 2 + (int) translationY;
            int childRight = childLeft + scaledWidth;
            int childBottom = childTop + scaledHeight;

            remoteView.layout(childLeft, childTop, childRight, childBottom);
        }

        applyTransformations();
    }

    private void applyTransformations() {
        if (remoteView == null) return;

        // 重置变换
        remoteView.setScaleX(1.0f);
        remoteView.setScaleY(1.0f);
        remoteView.setTranslationX(0f);
        remoteView.setTranslationY(0f);

        // 应用当前变换
        remoteView.setScaleX(scaleFactor);
        remoteView.setScaleY(scaleFactor);
        remoteView.setTranslationX(translationX);
        remoteView.setTranslationY(translationY);
    }

    // 以下触摸事件处理方法与之前相同
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (remoteView == null) return false;
        int pointerCount = event.getPointerCount();
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "ACTION_DOWN onTouchEvent: pointerCount = " + pointerCount);
                handleActionDown(event);
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                Log.i(TAG, "ACTION_POINTER_DOWN onTouchEvent: pointerCount = " + pointerCount);
                handlePointerDown(event);
                break;

            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "ACTION_MOVE onTouchEvent: pointerCount = " + pointerCount);
                handleActionMove(event);
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                Log.i(TAG, "ACTION_UP onTouchEvent: pointerCount = " + pointerCount);
                handleActionUp();
                break;

            case MotionEvent.ACTION_POINTER_UP:
                Log.i(TAG, "ACTION_POINTER_UP onTouchEvent: pointerCount = " + pointerCount);
                handlePointerUp(event);
                break;
        }

        return true;
    }

    private void handleActionDown(MotionEvent event) {
        activePointerId = event.getPointerId(0);
        lastTouchX = event.getX();
        lastTouchY = event.getY();
        touchDownTime = System.currentTimeMillis();
        isScaling = false;
        isDragging = false;
    }

    private void handlePointerDown(MotionEvent event) {
        if (event.getPointerCount() == 2) {
            isScaling = true;
            lastTouchDistance = getDistance(event);
        }
    }

    private void handleActionMove(MotionEvent event) {
        if (isScaling && event.getPointerCount() == 2) {
            // 双指缩放处理
            float newDistance = getDistance(event);
            if (newDistance > 10f) {
                float scale = newDistance / lastTouchDistance;
                float newScaleFactor = scaleFactor * scale;

                // 确保缩放范围在1.0f到3.0f之间
                newScaleFactor = Math.max(MIN_SCALE, Math.min(newScaleFactor, MAX_SCALE));

                if (newScaleFactor != scaleFactor) {
                    scaleFactor = newScaleFactor;

                    // 当缩放回到1.0f时，重置位置
                    if (scaleFactor == 1.0f) {
                        translationX = 0f;
                        translationY = 0f;
                    }

                    ensureBounds();
                    applyTransformations();
                }

                lastTouchDistance = newDistance;
            }
        } else if (!isScaling && activePointerId != INVALID_POINTER_ID) {
            // 单指移动处理
            int pointerIndex = event.findPointerIndex(activePointerId);
            if (pointerIndex == -1) return;

            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);

            if (!isDragging && scaleFactor != 1.0f) {
                isDragging = true;
            }

            if (isDragging) {
                float dx = x - lastTouchX;
                float dy = y - lastTouchY;

                translationX += dx;
                translationY += dy;
                ensureBounds();
                applyTransformations();
            } else if (scaleFactor == 1.0f) {
                handleDirectionOrClick(x, y);
            }

            lastTouchX = x;
            lastTouchY = y;
        }
    }

    private void handleActionUp() {
        if (!isDragging && !isScaling && scaleFactor == 1.0f) {
            if (System.currentTimeMillis() - touchDownTime < 200) {
                handleClick(lastTouchX, lastTouchY);
            }
        }
        activePointerId = INVALID_POINTER_ID;
        isScaling = false;
        isDragging = false;


    }

    private void handlePointerUp(MotionEvent event) {
        int pointerIndex = event.getActionIndex();
        int pointerId = event.getPointerId(pointerIndex);

        if (pointerId == activePointerId) {
            int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            if (newPointerIndex < event.getPointerCount()) {
                activePointerId = event.getPointerId(newPointerIndex);
                lastTouchX = event.getX(newPointerIndex);
                lastTouchY = event.getY(newPointerIndex);
            } else {
                activePointerId = INVALID_POINTER_ID;
            }
        }

        if (event.getPointerCount() < 2) {
            isScaling = false;
        }
    }

    private void ensureBounds() {
        int width = getWidth();
        int height = getHeight();
        int scaledWidth = (int) (width * scaleFactor);
        int scaledHeight = (int) (height * scaleFactor);

        // 计算最大可移动范围
        float maxTranslationX = Math.max(0, (scaledWidth - width) / 2f);
        float maxTranslationY = Math.max(0, (scaledHeight - height) / 2f);

        // 当缩放为1.0f时，强制位置归零
        if (scaleFactor == 1.0f) {
            translationX = 0f;
            translationY = 0f;
        } else {
            // 限制平移范围
            translationX = Math.max(-maxTranslationX, Math.min(translationX, maxTranslationX));
            translationY = Math.max(-maxTranslationY, Math.min(translationY, maxTranslationY));
        }
    }

    private float getDistance(MotionEvent event) {
        if (event.getPointerCount() < 2) return 0f;

        float x1 = event.getX(0);
        float y1 = event.getY(0);
        float x2 = event.getX(1);
        float y2 = event.getY(1);

        return (float) Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
    }


    private void handleDirectionOrClick(float x, float y) {
        // 方向滑动检测逻辑
        float dx = x - lastTouchX;
        float dy = y - lastTouchY;

        if (Math.abs(dx) > 10 || Math.abs(dy) > 10) {
            // 滑动事件
            double angle = Math.toDegrees(Math.atan2(dy, dx));
            angle = (angle + 360) % 360;

            if (angle >= 45 && angle < 135) {
                Log.d(TAG, "向下滑动");
            } else if (angle >= 135 && angle < 225) {
                Log.d(TAG, "向左滑动");
            } else if (angle >= 225 && angle < 315) {
                Log.d(TAG, "向上滑动");
            } else {
                Log.d(TAG, "向右滑动");
            }
        }
    }

    private void handleClick(float x, float y) {
        int width = getWidth();
        int height = getHeight();

        if (y < height / 3) {
            Log.d(TAG, "点击了上方区域");
        } else if (y > height * 2 / 3) {
            Log.d(TAG, "点击了下放区域");
        } else if (x < width / 3) {
            Log.d(TAG, "点击了左侧区域");
        } else if (x > width * 2 / 3) {
            Log.d(TAG, "点击了右侧区域");
        } else {
            Log.d(TAG, "点击了中央区域");
        }
    }
}